<!-- Radio.svelte -->
<script lang="ts">
	import { getContext } from 'svelte';
	import { RADIO_GROUP_CONTEXT_KEY } from './context';
	import type { RadioGroupContext, Variant } from './types';

	// 使用 let 声明 props 解构，确保 modelValue 可修改
	let {
		value,
		label = '',
		disabled = false,
		name = `radio-${Math.random().toString(36).slice(2, 11)}`,
		size = 'md',
		variant = 'primary',
		className = '',
		buttonStyle = false,
		border = false,
		fill = '',
		textColor = '',
		// 在 $props 解构中直接用 $bindable() 声明可绑定属性
		modelValue = $bindable(),
		onchange = () => {}
	} = $props<{
		value: any;
		label?: string | number;
		disabled?: boolean;
		name?: string;
		size?: 'sm' | 'md' | 'lg';
		variant?: Variant;
		className?: string;
		buttonStyle?: boolean;
		border?: boolean;
		fill?: string;
		textColor?: string;
		modelValue?: any;
		onchange?: (value: any) => void;
	}>();

	// 响应式状态
	let isChecked = $state(false);
	let unregisterGroup = $state<(() => void) | undefined>(undefined);

	// 获取单选框组上下文
	const radioGroupContext = getContext<RadioGroupContext | undefined>(RADIO_GROUP_CONTEXT_KEY);

	// 合并配置变量
	const isDisabled = $derived(radioGroupContext?.disabled || disabled);
	const isSize = $derived(radioGroupContext?.size || size);
	const isVariant = $derived(radioGroupContext?.variant || variant);
	const isButtonStyle = $derived(radioGroupContext?.buttonStyle || buttonStyle);
	const isBorder = $derived(radioGroupContext?.border || border);
	const isFill = $derived(radioGroupContext?.fill || fill);
	const isName = $derived(radioGroupContext?.name || name);
	const isTextColor = $derived(radioGroupContext?.textColor || textColor);

	// 监听 modelValue 变化，确保选中状态同步
	$effect(() => {
		isChecked = modelValue === value;
	});

	// 注册到组 + 组件卸载清理
	$effect(() => {
		if (radioGroupContext) {
			const unregister = radioGroupContext.register({
				value,
				currentChecked: isChecked,
				updateChecked: (checked) => {
					isChecked = checked;
				}
			});

			// 立即更新注销函数
			unregisterGroup = unregister;

			// 组件销毁时注销
			return () => {
				unregister?.();
			};
		}
	});

	// 当本地选中状态变化时，同步更新modelValue
	$effect(() => {
		if (!radioGroupContext && isChecked) {
			modelValue = value;
		}
	});

	// 点击事件处理
	function handleRadioClick() {
		if (isDisabled) return;

		if (radioGroupContext) {
			radioGroupContext.onToggle(value);
		} else {
			isChecked = true;
			modelValue = value; // 直接修改 modelValue
			onchange(value);
		}
	}

	// 键盘事件处理
	function handleRadioKeydown(e: KeyboardEvent) {
		if (isDisabled) return;

		if (e.key === 'Enter' || e.key === ' ') {
			e.preventDefault();
			handleRadioClick();
		}
	}
</script>

<div
	class={`radio-wrapper ${className}`}
	onclick={handleRadioClick}
	onkeydown={handleRadioKeydown}
	role="radio"
	aria-checked={isChecked}
	aria-disabled={isDisabled}
	tabindex={isDisabled ? -1 : 0}
>
	<div
		class="custom-radio size--{isSize} {isChecked ? 'is-checked' : ''} {isDisabled
			? 'custom-radio--disabled'
			: ''} {isButtonStyle ? 'custom-radio--button' : ''} {isBorder ? 'custom-radio--border' : ''}"
		style="
			--radio-color: {isFill || `var(--color-${isVariant}-500)`};
			{isTextColor ? `--radio-text-color: ${isTextColor};` : ''}
		"
	>
		{#if isButtonStyle}
			<span class="radio-button">{label}</span>
		{:else}
			<div class="radio-container">
				{#if isChecked}
					<div class="radio-icon"></div>
				{/if}
			</div>
			{#if label}
				<span class="custom-radio__label">{label}</span>
			{/if}
		{/if}
	</div>
	<input
		type="radio"
		name={isName}
		{value}
		checked={isChecked}
		disabled={isDisabled}
		style="display: none;"
	/>
</div>

<style lang="scss" scoped>
	.radio-wrapper {
		display: inline-block;
		user-select: none;
	}

	.custom-radio {
		display: inline-flex;
		align-items: center;
		vertical-align: middle;
		gap: 8px;

		&:not(.custom-radio--disabled) {
			cursor: pointer;
		}

		&.custom-radio--disabled {
			opacity: 0.4;
			cursor: not-allowed;
		}

		.radio-container {
			display: flex;
			align-items: center;
			justify-content: center;
			border: 1px solid var(--color-info-300);
			border-radius: 50%;
			flex-shrink: 0;
			box-sizing: content-box;

			.radio-icon {
				border-radius: 50%;
				background-color: var(--radio-color);
			}
		}

		.radio-button {
			display: block;
		}
	}

	/* 尺寸样式 */
	.size--sm {
		height: 26px;
		line-height: 26px;

		&.custom-radio--border {
			padding: 0 8px;
		}

		.radio-container {
			width: 14px;
			height: 14px;

			.radio-icon {
				width: 6px;
				height: 6px;
			}
		}

		.custom-radio__label {
			font-size: 12px;
		}

		.radio-button {
			padding: 0 12px;
			font-size: 12px;
		}
	}

	.size--md {
		height: 28px;
		line-height: 28px;

		&.custom-radio--border {
			padding: 0 10px;
		}

		.radio-container {
			width: 15px;
			height: 15px;

			.radio-icon {
				width: 7px;
				height: 7px;
			}
		}

		.custom-radio__label {
			font-size: 13px;
		}

		.radio-button {
			padding: 0 14px;
			font-size: 13px;
		}
	}

	.size--lg {
		height: 32px;
		line-height: 32px;

		&.custom-radio--border {
			padding: 0 12px;
		}

		.radio-container {
			width: 16px;
			height: 16px;

			.radio-icon {
				width: 8px;
				height: 8px;
			}
		}

		.custom-radio__label {
			font-size: 14px;
		}

		.radio-button {
			padding: 0 16px;
			font-size: 14px;
		}
	}

	/* 选中状态样式 */
	.custom-radio:not(.custom-radio--disabled).is-checked {
		.radio-container {
			border-color: var(--radio-color);
		}

		.custom-radio__label {
			color: var(--radio-color);
		}
	}

	/* 边框样式 */
	.custom-radio--border {
		border: 1px solid var(--color-info-300);
		border-radius: 4px;
		transition: all 0.2s ease;
		background: var(--color-page);

		&:not(.custom-radio--disabled).is-checked {
			border-color: var(--radio-color);
		}

		.radio-container {
			border-color: var(--color-info-400);
			background-color: var(--color-page);
		}
	}

	/* 按钮样式 */
	.custom-radio--button {
		box-shadow: -1px 0 0 0 var(--color-info-300);

		&.is-checked {
			.radio-button {
				background-color: var(--radio-color);
				border-color: var(--radio-color);
				color: var(--color-page);
			}
		}
	}
</style>
